package org.fall.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.fall.system.constant.BackstageConstant;
import org.fall.system.dao.MemberLeaderMapper;
import org.fall.system.dao.MemberMapper;
import org.fall.system.model.ResultEntity;
import org.fall.system.model.dto.MemberDTO;
import org.fall.system.model.dto.MemberQueryDTO;
import org.fall.system.model.po.LeaderInfoPO;
import org.fall.system.model.po.MemberPO;
import org.fall.system.model.vo.MemberVO;
import org.fall.system.service.MemberManagementService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author sprogFall
 * @since 2021/4/11 9:07
 */
@Service
public class MemberManagementServiceImpl implements MemberManagementService {

    @Resource
    private MemberMapper memberMapper;

    @Resource
    private MemberLeaderMapper memberLeaderMapper;

    @Override
    public ResultEntity getMemberList(MemberQueryDTO dto) {
        QueryWrapper<MemberPO> queryWrapper = new QueryWrapper<>();
        // deleteToken==0 表示未被删除
        queryWrapper.eq("delete_token", 0);
        Page<MemberPO> poPage = getMemberPOPage(dto, queryWrapper);
        return ResultEntity.successWithDataAndCount(poPage.getRecords(), poPage.getTotal(), 0);
    }

    @Override
    public ResultEntity getDeletedMemberList(MemberQueryDTO dto) {
        QueryWrapper<MemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("delete_token", 0);
        Page<MemberPO> poPage = getMemberPOPage(dto, queryWrapper);
        return ResultEntity.successWithDataAndCount(poPage.getRecords(), poPage.getTotal(), 0);
    }

    private Page<MemberPO> getMemberPOPage(MemberQueryDTO dto, QueryWrapper<MemberPO> queryWrapper) {
        if (!StringUtils.isEmpty(dto.getKeyword())) {
            String keyword = dto.getKeyword();
            // keyword匹配登录名、昵称与邮箱
            queryWrapper.and(true, qw -> qw.like("username", keyword).or().like("name", keyword).or().like("email", keyword));
        }
        return memberMapper.selectPage(new Page<>(dto.getPage(), dto.getLimit()), queryWrapper);
    }

    @Override
    public ResultEntity deleteMember(Integer id) {
        MemberPO po = new MemberPO();
        po.setId(id);
        // 时间格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        po.setDeleteToken(LocalDateTime.now().format(dateTimeFormatter));
        int update = memberMapper.updateById(po);
        if (update == 1) {
            return ResultEntity.successWithoutData();
        }
        return ResultEntity.failed(BackstageConstant.DELETE_FAILED);
    }

    @Override
    public ResultEntity restoreDeletedMember(Integer id) {
        MemberPO po = new MemberPO();
        po.setId(id);
        po.setDeleteToken("0");
        int update = memberMapper.updateById(po);
        if (update == 1) {
            return ResultEntity.successWithoutData();
        }
        return ResultEntity.failed(BackstageConstant.RESTORE_FAILED);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity batchDeleteMembers(List<Integer> list) {
        MemberPO po = new MemberPO();
        po.setDeleteToken(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        QueryWrapper<MemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", list);
        int update = memberMapper.update(po, queryWrapper);
        if (update != list.size()) {
            throw new RuntimeException(BackstageConstant.DELETE_FAILED);
        }
        return ResultEntity.successWithoutData();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity batchRestoreDeletedMember(List<Integer> list) {
        MemberPO po = new MemberPO();
        po.setDeleteToken("0");
        QueryWrapper<MemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", list);
        int update = memberMapper.update(po, queryWrapper);
        if (update != list.size()) {
            throw new RuntimeException(BackstageConstant.RESTORE_FAILED);
        }
        return ResultEntity.successWithoutData();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity completeDeleteMember(Integer id) {
        int delete = memberMapper.deleteById(id);
        if (delete == 1) {
            // 删除leader表中的数据
            memberLeaderMapper.delete(new QueryWrapper<LeaderInfoPO>().eq("leader_id", id));
            return ResultEntity.successWithoutData();
        }
        return ResultEntity.failed(BackstageConstant.DELETE_FAILED);
    }

    @Override
    public MemberVO getMemberById(Integer id) {
        MemberPO po = memberMapper.selectById(id);
        MemberVO vo = new MemberVO();
        BeanUtils.copyProperties(po, vo);
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity editMemberInfo(MemberDTO dto) {
        QueryWrapper<MemberPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", dto.getUsername());
        MemberPO po = new MemberPO();
        BeanUtils.copyProperties(dto, po);
        if (dto.getLeaderId() > 0) {
            // 根据leader_id得到leader_name
            LeaderInfoPO leaderInfo = memberLeaderMapper.selectOne(new QueryWrapper<LeaderInfoPO>().eq("leader_id", dto.getLeaderId()));
            po.setLeaderName(leaderInfo.getLeaderName());
        }
        int update = memberMapper.update(po, queryWrapper);
        if (update == 1) {
            if (!isGeneralUser(po.getTitle())) {
                // 确认当前leader表中是否已经有当前用户
                int count = memberLeaderMapper.selectCount(new QueryWrapper<LeaderInfoPO>().eq("leader_id", po.getId()));
                if (count == 0) {
                    // 当前leader表没有用户 进行插入操作
                    Integer leaderCount = addLeader(po);
                    if (leaderCount != 1) {
                        throw new RuntimeException(BackstageConstant.UPDATE_FAILED);
                    }
                }
            }
            // 更新表与插入表操作都正常，返回success
            return ResultEntity.successWithoutData();
        }
        return ResultEntity.failed(BackstageConstant.UPDATE_FAILED);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultEntity saveMember(MemberDTO dto) {
        MemberPO po = new MemberPO();
        BeanUtils.copyProperties(dto, po);
        if (po.getLeaderId() > 0) {
            LeaderInfoPO leaderInfo = memberLeaderMapper.selectOne(new QueryWrapper<LeaderInfoPO>().eq("leader_id", dto.getLeaderId()));
            po.setLeaderName(leaderInfo.getLeaderName());
        }
        int insert = memberMapper.insert(po);
        if (insert == 1) {
            if (!isGeneralUser(po.getTitle())) {
                // 非普通用户，加入领导表
                int leaderInsert = addLeader(po);
                if (leaderInsert != 1) {
                    // 如果leader表插入失败，抛出异常，进行回滚
                    throw new RuntimeException(BackstageConstant.REGISTER_FAILED);
                }
            }
            return ResultEntity.successWithoutData();
        }
        return ResultEntity.failed(BackstageConstant.REGISTER_FAILED);
    }

    @Override
    public List<LeaderInfoPO> getLeaderList() {
        return memberLeaderMapper.selectList(null);
    }


    /**
     * 根据岗位判断是否是普通用户
     * @param title 职位名称
     * @return true:是普通用户 false:是leader
     */
    private boolean isGeneralUser(String title) {
        String[] leaderArray = {"组长", "主管", "经理", "董事"};
        for (String str : leaderArray) {
            if (title.contains(str)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 向leader表添加数据
     * @param po po
     * @return 添加结果
     */
    private Integer addLeader(MemberPO po) {
        LeaderInfoPO leaderInfo = new LeaderInfoPO();
        leaderInfo.setLeaderId(po.getId());
        leaderInfo.setLeaderName(po.getName());
        System.out.println(leaderInfo);
        return memberLeaderMapper.insert(leaderInfo);
    }
}
